error = require '../error'
log = require '../log'

UserService = require '../service/UserService'

SecurityCodeService = require('../service/SecurityCodeService')

checkPasswordFormat = (password)->
    /^([a-zA-Z0-9]){8,20}$/.test password
exports.checkPasswordFormat = checkPasswordFormat

exports.clearUserSessionCookies = (ctx, app)->
    ctx.cookies.set(app + 'UserId', null, {signed: true, httpOnly: true})
    ctx.cookies.set(app + 'UserToken', null, {signed: true, httpOnly: true})

exports.gPing = ->
    if @state.user
        user = @state.user
        user2 = {
            userId: user._id, admin: user.admin
            urlPermissions: user.urlPermissions, entityPermissions: user.entityPermissions,
            menuPermissions: user.menuPermissions
        }
        user2.roles = {}
        if user.roles
            for roleId in user.roles
                role = yield from UserService.gRoleById(roleId)
                user2.roles[role.name] = {
                    urlPermissions: role.urlPermissions, entityPermissions: role.entityPermissions,
                    menuPermissions: role.menuPermissions
                }
        @body = user2
    else
        @status = 401
    yield return

# 用户登录页面
exports.toSignInPage = ->
    @render('sign-in')
    yield return

# 用户登录接口
exports.gSignIn = (next)->
    req = @request.body
    return @status == 400 unless req.username and req.password

    session = yield from UserService.gSignIn(@state.subApp, req.username, req.password)
    @body = {userId: session.userId}

    app = @state.subApp
    @cookies.set(app + 'UserId', session.userId, {signed: true, httpOnly: true})
    @cookies.set(app + 'UserToken', session.userToken, {signed: true, httpOnly: true})
    yield next

# 登出用户界面
exports.toSignOutPage = ->
    yield from UserService.gSignOut(@state.subApp, @state.user)

    # 清cookies
    app = @state.subApp
    exports.clearUserSessionCookies(this, app)

    @redirect('/sign-in')

# 登出接口
exports.gSignOut = ->
    yield from UserService.gSignOut(@state.userId)

    # 清cookies
    app = @state.subApp
    exports.clearUserSessionCookies(this, app)

    @status = 204

# 到修改密码页面
exports.toChangePasswordPage = ->
    @render('change-password')
    yield return

# 用户修改密码接口
exports.gChangePassword = ->
    req = @request.body

    unless checkPasswordFormat(req.newPassword)
        throw new errors.UserError('BadPasswordFormat')

    yield from UserService.gChangePassword(@state.user._id, req.oldPassword, req.newPassword)

    # 清cookies
    app = @state.subApp
    exports.clearUserSessionCookies(this, app)

    @status = 204

# 到忘记密码页面
exports.toResetPasswordPage = ->
    targetUrl = @query.targetUrl
    @render('forget-password', {targetUrl})
    yield return

# 通过手机/email重置密码
# phone/email, password, securityCode
exports.gResetPassword = ->
    req = @request.body

    unless checkPasswordFormat(req.password)
        throw new errors.UserError('BadPasswordFormat')

    if req.phone?
        SecurityCodeService.check(req.phone, req.securityCode)
        yield from UserService.gResetPasswordByPhone(req.phone, req.password)
    else if req.email?
        SecurityCodeService.check(req.email, req.securityCode)
        yield from UserService.gResetPasswordByEmail(req.email, req.password)
    else
        @status = 400

    @status = 204

# 到修改手机页面
exports.toChangePhonePage = ->
    @render('change-phone')
    yield return

# 用户修改手机接口
exports.gChangePhone = ->
    req = @request.body

    # 检查验证码
    SecurityCodeService.check(req.phone, req.securityCode)

    yield from UserService.gChangePhone(@state.user._id, req.phone)

    @status = 204

# 到修改 Email 页面
exports.toChangeEmailPage = ->
    @render('change-email')
    yield return

# 用户修改 Email
exports.gChangeEmail = ->
    req = @request.body

    # 检查验证码
    SecurityCodeService.check(req.email, req.securityCode)

    yield from UserService.gChangeEmail(@state.user._id, req.email)

    @status = 204

